﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace LogfileEditor
{
    public static class EditorCore
    {
        static Regex regex = new Regex(@"(?<operator>and|or|start)\s*(?<type>[+\-])(\((?<keyword>.*?)\))", RegexOptions.ExplicitCapture);

        /// <summary>
        /// 判断表达式是否有效
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        public static bool ExpressionIsValid(string expression)
        {
            return GetMatches(expression).Count > 0;
        }

        /// <summary>
        /// 拆解表达式
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        public static MatchCollection GetMatches(string expression)
        {
            expression = expression.Trim();
            expression = expression.Trim(new char[] { 'a', 'n', 'd', 'o', 'r', ' ' });
            var matches = regex.Matches("and " + expression);
            return matches;
        }
        /// <summary>
        /// 判断是否应该保留行
        /// </summary>
        /// <param name="line"></param>
        /// <param name="keywordExpression"></param>
        /// <returns></returns>
        public static bool ShouldKeepLine(string line, string keywordExpression)
        {
            //Regex regex = new Regex(@"(?<operator>and|or|start)\s*(?<type>[+\-])(\((?<keyword>.*?)\))", RegexOptions.ExplicitCapture);
            //keywordExpression = keywordExpression.Trim();
            //keywordExpression = keywordExpression.Trim(new char[] { 'a', 'n', 'd', 'o', 'r', ' ' });
            var matches = GetMatches(keywordExpression);
            //是否满足条件, 1表示满足, 0表示不满足, -1表示没有and或or
            var isSatisfied_and = -1;
            var isSatisfied_or = -1;

            var andList = new List<int>();
            var orList = new List<int>();

            if (matches.Count > 0)
            {
                foreach (Match match in matches)
                {
                    string keyword = match.Groups["keyword"].Value;
                    string type = match.Groups["type"].Value;
                    string operatorStr = match.Groups["operator"].Value;

                    bool containsKeyword = line.Contains(keyword);

                    if (operatorStr == "and")
                    {
                        if (type == "+")
                        {
                            if (containsKeyword)
                            {
                                isSatisfied_and = 1;
                            }
                            else
                            {
                                isSatisfied_and = 0;
                            }
                        }
                        if (type == "-")
                        {
                            if (!containsKeyword)
                            {
                                isSatisfied_and = 1;
                            }
                            else
                            {
                                isSatisfied_and = 0;
                            }
                        }
                        andList.Add(isSatisfied_and);
                    }
                    else if (operatorStr == "or")
                    {
                        if (type == "+")
                        {
                            if (containsKeyword)
                            {
                                isSatisfied_or = 1;
                            }
                            else
                            {
                                isSatisfied_or = 0;
                            }
                        }
                        if (type == "-")
                        {
                            if (!containsKeyword)
                            {
                                isSatisfied_or = 1;
                            }
                            else
                            {
                                isSatisfied_or = 0;
                            }
                        }
                        orList.Add(isSatisfied_or);
                    }
                }

                //如果只有and, 则判断是否满足and条件
                if (andList.Any(x => x == 0) && !orList.Any())
                {
                    return false;
                }

                //如果只有and, 则判断是否满足and条件
                if (!andList.Any(x => x == 0) && !orList.Any())
                {
                    return true;
                }
                //如果只有or, 则判断是否满足or条件
                if (orList.Any(x => x == 1))
                {
                    return true;
                }

                //如果有and和or, 则判断是否满or条件
                if (andList.Any(x => x == 0) && orList.Any(x => x == 1))
                {
                    return true;
                }

                if (!andList.Any(x => x == 0) && orList.Any(x => x == 0))
                {
                    return true;
                }

                if (andList.Any(x => x == 1) && !orList.Any(x => x == 0))
                {
                    return true;
                }

                //if (isSatisfied_and == 1 && isSatisfied_or == 1)
                //{
                //    return true;
                //}
                //if (isSatisfied_and == -1 && isSatisfied_or == -1)
                //{
                //    return false;
                //}
                //if (isSatisfied_and == 1 && isSatisfied_or == -1)
                //{
                //    return true;
                //}
                //if (isSatisfied_and == -1 && isSatisfied_or == 1)
                //{
                //    return true;
                //}
                //if (isSatisfied_and == 0 && isSatisfied_or == 1)
                //{
                //    return true;
                //}
                //if (isSatisfied_and == 1 && isSatisfied_or == 0)
                //{
                //    return true;
                //}

                return false;
            }
            else
            {
                return false;
            }
        }
    }
}
